package com.gitee.utils;

import cn.hutool.core.util.StrUtil;
import com.gitee.enums.ResponseEnum;
import com.gitee.exception.LoginException;
import com.gitee.exception.UserException;
import com.gitee.pojo.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Slf4j
public class JwtUtil {

    /**
     * 过期时间，毫秒，一周
     */
    public static final long EXPIRE = 1000 * 60 * 60 * 24 * 7;


    /**
     * 秘钥
     */
    public static final String SECRET = "canteen-wx";


    /**
     * 生成jwt
     *
     * @param user
     * @return
     */
    public static String createJWT(User user) {
        if (user == null) {
            throw new UserException(ResponseEnum.LOGIN_FAIL);
        }
        return Jwts.builder().setSubject(user.getId().toString())
                .claim("userId", user.getId())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                .signWith(SignatureAlgorithm.HS256, SECRET).compact();
    }

    /**
     * 校验token
     *
     * @param token
     * @return
     */
    public static Claims checkJWT(String token) {
        try {
            return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            e.printStackTrace();
            throw new LoginException(ResponseEnum.NO_LOGIN);
        }
    }

    public static Integer getUserId(HttpServletRequest request) {
        String token = request.getHeader("token");
        // 判断token是否存在
        if (StrUtil.isBlank(token)) {
            throw new LoginException(ResponseEnum.NO_LOGIN);
        }
        // 获取载荷
        Claims claims = JwtUtil.checkJWT(token);
        // 判断token是否过期
        long expireTime = claims.getExpiration().getTime();
        if (expireTime <  new Date().getTime()) {
            throw new LoginException(ResponseEnum.NO_LOGIN);
        }
        // 判断用户状态
        Integer userId = (Integer)claims.get("userId");
        if (userId == null) {
            throw new LoginException(ResponseEnum.NO_LOGIN);
        }
        return userId;
    }
}
